Fediverse GoToSocial Bot zur Weiterleitung von Website News erstellen
Bot Definition im Kontext des Fediverse
Ein automatisch gesteuertes Programm, dass einen oder mehrere Aufgaben erfüllt und im Ergebnis eine Fediverse Nachricht verfasst. Beispiele:
- Wetterbenachrichtigungen
- Informationen von Websiten weitergeben
- Informationen von öffentlichen Services weitergeben (z.B. Warnmeldungen des Katastrophenschutzes)
- Zufällige Texte posten (Zitate, Witze …)
- ETL Jobs (Extract, Transform, Load): Daten holen, manipulieren/berechnen/in Beziehung zu anderen Daten setzen und sie in das Zielsystem (Fediverse) laden
Mein Use Case
Für Zöliakie-Betroffene gibt es die Deutsche Zöliakie Gesellschaft (DZG), ein Verein, der Lobby, Informationen und Selbsthilfe bei Glutenunverträglichkeit organisiert. Leider ist die DZG wie viele Vereine und Instiutionen auch (noch) nicht im Fediverse aktiv. Bis es soweit ist, will ich mit meinem (Beispiel-) Bot Neuigkeiten der DZG ins Fediverse weiterleiten.
Was wird für den Bot benötigt?
- Grundlagen Wissen der Programmierung und von HTML
- Eine Fediverse Instanz, auf der man einen Bot betreiben kann (für andere Plattformen wie Mastodon müßte alles bis auf den API Call passen)
- Einen dauerhaft mit dem Web verbundenen Server (VPS, RaspberryPi etc.), der zu geplanten Uhrzeiten ein PHP-Skript ausführen kann
Anleitung
Zusammengefasst besteht das gesamte Konstrukt aus folgenden Prozesse
- Website Daten auslesen (Web Scraping)
- Die passenden Informationen identifizieren und aufbereiten
- Diese Informationen als neuer Fediverse Status (=Nachricht) veröffentlichen
Grobe Schritt-für-Schritt-Anleitung
- Inspektion der Website: Welche Tags werden im Quellcode bei Newseinträgen verwendet?
Python Script Teil 1 (Beautiful Soup)
Sollte alle gefundenen Elemente testweise in der Shell ausgeben. Hinweis: Das folgende Skript ist bewusst simpel gehalten
import requests from bs4 import BeautifulSoup from datetime import datetime dateFormatter = "DATE_FORMAT_USED_ON_WEBSITE" url = "URL_WITH_CONTENT_TO_SCRAPE" response = requests.get(url) if response.status_code == requests.codes.ok: html_content = response.text print("Request was successful!") soup = BeautifulSoup(html_content, 'html.parser') mydivs = soup.find_all("div", {"class": "slider_textcontainer"}) for mydiv1 in mydivs: title_element = mydiv1.find("h2") content_element = mydiv1.find("p") time_element=datetime.strptime(mydiv1.find("time").text, dateFormatter) print(title_element.text) print(mydiv1.find("time").text) print(content_element.text) print("==========") else: print("Failed to retrieve data. Status code: response.status_code}")
GoToSocial Account anlegen
Da GoToSocial noch in der Entwicklung ist, gibt es im Admin Backend noch keine einfache Möglichkeit, einen neuen Account anzulegen. Hierzu ist Zugriff auf den Server gefragt (in meinem Beispiel auf einem Debian Yunohost Server):
. /var/www/gotosocial ./gotosocial admin account create --username USERNAME --email ACCOUNT@EMAIL.DE --password SECRET_PASSWORD --config-path config.yaml
Bearer Token auslesen
Geht etwas aufwändiger mit einem Rest Tool (und der GTS API Doku) oder einfacher über einen Service wie https://takahashim.github.io/mastodon-access-token/ (dem man dann allerdings Vertrauen können muss)
Python Script Teil 2 (inkl. Fediverse Status erstellen)
Hinweis: Auch dieses Skript ist bewusst simpel gehalten und würde je nach Ausführungshäufigkeit doppelte Einträge erzeugen oder Neuigkeiten verpassen
... for mydiv1 in mydivs: title_element = mydiv1.find("h2") content_element = mydiv1.find("p") time_element=datetime.strptime(mydiv1.find("time").text, dateFormatter) if time_element.date() == datetime.now().date(): #POSTING A STATUS TO THE FEDIVERSE requests.post( url="URL_OF_GO_TO_SOCIAL_INSTANCE/api/v1/statuses", headers={"Authorization": "Bearer TOKEN"}, json={"status":title_element.text+" (Datum:"+mydiv1.find("time").text+ ")\n\n"+content_element.text+"\n#YOUR_HASHTAGS","visibility": "public"}, ) else: print ("Older entries found:" +str(time_element)) ...
- Script auf dem Server platzieren und manuell ausführen
Cronjob erstellen
In meinem Beispielskript wird nur abgeprüft, ob das Datum des Newseintrags einer Website dem heutigen Datum entspricht. Daher dürfte das Skript nur 1x täglich ablaufen, möglichst um eine Uhrzeit, bei der keine neuen Nachrichten mehr zu erwarten sind
Optimieren
In meinem Fall habe ich die Erkennung neuer Einträge erweitert, in dem die bisher gefundenen und weitergeleiteten Nachrichten Titel in einem Textfile gespeichert werden. Dieses File wird dann bei jedem Lauf auf Dubletten iteriert und nur wirklich neue Einträge werden weitergeleitet. Dadurch kann das Script jetzt öfters am Tag laufen.